package com.github.syncrepo.model;

/**
 * Configuration model for repository synchronization
 */
public class SyncConfig {
    /**
     * Reference type enum - supports BRANCH, TAG, or COMMIT
     */
    public enum RefType {
        BRANCH, TAG, COMMIT
    }

    private String sourceRepoUrl;
    private String sourceBranch;
    private String targetRepoUrl;
    private String targetBranch;
    private String accessToken;
    private boolean keepLocalCopy;
    private String workDir;
    
    // New fields for tag support
    private RefType sourceRefType = RefType.BRANCH;  // Default to BRANCH for backward compatibility
    private RefType targetRefType = RefType.BRANCH;
    private boolean forceSync = false;  // For force push when tag exists
    
    // SSH key path (optional, if not set, will use default SSH keys)
    private String sshKeyPath;

    public SyncConfig() {
        this.keepLocalCopy = false;
    }

    public String getSourceRepoUrl() {
        return sourceRepoUrl;
    }

    public void setSourceRepoUrl(String sourceRepoUrl) {
        this.sourceRepoUrl = sourceRepoUrl;
    }

    public String getSourceBranch() {
        return sourceBranch;
    }

    public void setSourceBranch(String sourceBranch) {
        this.sourceBranch = sourceBranch;
    }

    public String getTargetRepoUrl() {
        return targetRepoUrl;
    }

    public void setTargetRepoUrl(String targetRepoUrl) {
        this.targetRepoUrl = targetRepoUrl;
    }

    public String getTargetBranch() {
        return targetBranch;
    }

    public void setTargetBranch(String targetBranch) {
        this.targetBranch = targetBranch;
    }

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public boolean isKeepLocalCopy() {
        return keepLocalCopy;
    }

    public void setKeepLocalCopy(boolean keepLocalCopy) {
        this.keepLocalCopy = keepLocalCopy;
    }

    public String getWorkDir() {
        return workDir;
    }

    public void setWorkDir(String workDir) {
        this.workDir = workDir;
    }

    public RefType getSourceRefType() {
        return sourceRefType;
    }

    public void setSourceRefType(RefType sourceRefType) {
        this.sourceRefType = sourceRefType;
    }

    public RefType getTargetRefType() {
        return targetRefType;
    }

    public void setTargetRefType(RefType targetRefType) {
        this.targetRefType = targetRefType;
    }

    public boolean isForceSync() {
        return forceSync;
    }

    public void setForceSync(boolean forceSync) {
        this.forceSync = forceSync;
    }

    public String getSshKeyPath() {
        return sshKeyPath;
    }

    public void setSshKeyPath(String sshKeyPath) {
        this.sshKeyPath = sshKeyPath;
    }

    @Override
    public String toString() {
        return "SyncConfig{" +
                "sourceRepoUrl='" + sourceRepoUrl + '\'' +
                ", sourceBranch='" + sourceBranch + '\'' +
                ", sourceRefType=" + sourceRefType +
                ", targetRepoUrl='" + targetRepoUrl + '\'' +
                ", targetBranch='" + targetBranch + '\'' +
                ", targetRefType=" + targetRefType +
                ", keepLocalCopy=" + keepLocalCopy +
                ", workDir='" + workDir + '\'' +
                ", forceSync=" + forceSync +
                '}';
    }

    public void validate() throws IllegalArgumentException {
        if (sourceRepoUrl == null || sourceRepoUrl.trim().isEmpty()) {
            throw new IllegalArgumentException("Source repository URL is required");
        }
        if (sourceBranch == null || sourceBranch.trim().isEmpty()) {
            throw new IllegalArgumentException("Source branch/tag/commit name is required");
        }
        if (targetRepoUrl == null || targetRepoUrl.trim().isEmpty()) {
            throw new IllegalArgumentException("Target repository URL is required");
        }
        if (targetBranch == null || targetBranch.trim().isEmpty()) {
            throw new IllegalArgumentException("Target branch/tag name is required");
        }
        
        // Check if SSH URL is used
        boolean isSshUrl = (sourceRepoUrl.startsWith("git@") || sourceRepoUrl.startsWith("ssh://")) ||
                          (targetRepoUrl.startsWith("git@") || targetRepoUrl.startsWith("ssh://"));
        
        // Token is only required for HTTP/HTTPS URLs
        if (!isSshUrl && (accessToken == null || accessToken.trim().isEmpty())) {
            throw new IllegalArgumentException("Git access token is required for HTTP/HTTPS URLs. " +
                    "For SSH URLs (git@...), SSH keys will be used instead.");
        }
        
        // Validate ref types
        if (sourceRefType == null) {
            throw new IllegalArgumentException("Source ref type is required");
        }
        if (targetRefType == null) {
            throw new IllegalArgumentException("Target ref type is required");
        }
    }
}

